// Package repository internal/repository/admin_repository.go
package repository

import (
	"errors"
	"gorm.io/gorm"
	"gozrd-admin-api/internal/entity/dto"
	"gozrd-admin-api/internal/entity/model"
	"gozrd-admin-api/internal/entity/query"
	"gozrd-admin-api/internal/entity/vo"
	"time"
)

// IAdminRepository 管理员仓库接口
type IAdminRepository interface {
	SysAdminDetail(dto dto.LoginDto) (sysAdmin model.SysAdmin, err error)
	GetSysAdminByUsername(username string) (sysAdmin model.SysAdmin, err error)
	CreateSysAdmin(roleId int, admin model.SysAdmin) error
	GetSysAdminInfo(Id int) (sysAdminInfoVo vo.SysAdminInfoVo, err error)
	UpdateSysAdmin(admin model.SysAdmin, roleId int) (model.SysAdmin, error)
	DeleteSysAdminById(id int) error
	GetSysAdminById(id int) (sysAdmin model.SysAdmin, err error)
	UpdateSysAdminStatus(id int, status int) error
	ResetSysAdminPassword(id int, password string) error
	UpdatePersonal(admin model.SysAdmin) (model.SysAdmin, error)
	UpdatePersonalPassword(id int, newPassword string) (model.SysAdmin, error)

	GetSysAdminList(query query.SysAdminQuery) (dto.AdminListResult, error)
	// 获取关联数据
	//GetSysAdminRoleById(adminId int) (int, error)
	//GetDeptById(deptId int) (model.SysDept, error)
	//GetPostById(postId int) (model.SysPost, error)
	//GetRoleById(roleId int) (model.SysRole, error)
}

// AdminRepository 管理员仓库实现
type AdminRepository struct {
	db *gorm.DB
}

// NewAdminRepository 创建管理员仓库
func NewAdminRepository(db *gorm.DB) IAdminRepository {
	return &AdminRepository{
		db: db,
	}
}

// SysAdminDetail  根据用户名获取管理员
func (r *AdminRepository) SysAdminDetail(dto dto.LoginDto) (sysAdmin model.SysAdmin, err error) {
	username := dto.Username
	err = r.db.Where("username = ?", username).First(&sysAdmin).Error
	return sysAdmin, err
}

// GetSysAdminByUsername 根据用户名查询用户  TODO  多余的
func (r *AdminRepository) GetSysAdminByUsername(username string) (sysAdmin model.SysAdmin, err error) {
	err = r.db.Where("username = ?", username).First(&sysAdmin).Error
	return sysAdmin, err
}

// GetSysAdminById 根据用户名查询用户  TODO  多余的
func (r *AdminRepository) GetSysAdminById(id int) (sysAdmin model.SysAdmin, err error) {
	err = r.db.Where("id = ?", id).First(&sysAdmin).Error
	return sysAdmin, err
}

var (
	userEixt = errors.New("用户已存在")
)

// CreateSysAdmin 创建管理员
func (r *AdminRepository) CreateSysAdmin(roleId int, admin model.SysAdmin) error {
	// 检查用户是否存在
	existingAdmin, err := r.GetSysAdminByUsername(admin.Username)
	if err != nil && err != gorm.ErrRecordNotFound {
		return err
	}
	if existingAdmin.ID > 0 {
		return userEixt
	}

	// 开启事务
	return r.db.Transaction(func(tx *gorm.DB) error {
		// 创建用户
		admin.CreateTime = time.Now()

		if err := tx.Create(&admin).Error; err != nil {
			return err
		}

		// 创建角色关联
		adminRole := model.SysAdminRole{
			AdminId: admin.ID,
			RoleId:  roleId,
		}

		if err := tx.Create(&adminRole).Error; err != nil {
			return err
		}

		return nil
	})
}

// GetSysAdminInfo 根据id查询用户详情
func (r *AdminRepository) GetSysAdminInfo(Id int) (sysAdminInfoVo vo.SysAdminInfoVo, err error) {
	err = r.db.Table("sys_admin").
		Select("sys_admin.*, sys_admin_role.role_id").
		Joins("LEFT JOIN sys_admin_role ON sys_admin.id = sys_admin_role.admin_id").
		Joins("LEFT JOIN sys_role ON sys_Admin_role.role_id = sys_role.id").
		First(&sysAdminInfoVo, Id).Error
	return sysAdminInfoVo, err
}

// UpdateSysAdmin 修改用户
func (r *AdminRepository) UpdateSysAdmin(admin model.SysAdmin, roleId int) (model.SysAdmin, error) {
	// 使用事务来确保操作的原子性
	tx := r.db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 查询用户
	var existingAdmin model.SysAdmin
	err := tx.First(&existingAdmin, admin.ID).Error
	if err != nil {
		tx.Rollback()
		return model.SysAdmin{}, err
	}

	// 更新字段
	existingAdmin.Username = admin.Username
	existingAdmin.PostId = admin.PostId
	existingAdmin.DeptId = admin.DeptId
	existingAdmin.Status = admin.Status
	existingAdmin.Nickname = admin.Nickname
	existingAdmin.Phone = admin.Phone
	existingAdmin.Email = admin.Email
	existingAdmin.Note = admin.Note

	// 保存用户信息
	if err := tx.Save(&existingAdmin).Error; err != nil {
		tx.Rollback()
		return model.SysAdmin{}, err
	}

	// 删除旧角色并创建新角色
	if err := tx.Where("admin_id = ?", admin.ID).Delete(&model.SysAdminRole{}).Error; err != nil {
		tx.Rollback()
		return model.SysAdmin{}, err
	}

	sysAdminRole := model.SysAdminRole{
		AdminId: admin.ID,
		RoleId:  roleId,
	}
	if err := tx.Create(&sysAdminRole).Error; err != nil {
		tx.Rollback()
		return model.SysAdmin{}, err
	}

	// 提交事务
	if err := tx.Commit().Error; err != nil {
		tx.Rollback()
		return model.SysAdmin{}, err
	}

	return existingAdmin, nil
}

// DeleteSysAdminById 根据id删除用户
// 修改后的Repository接口方法
func (r *AdminRepository) DeleteSysAdminById(id int) error {
	// 开启事务
	tx := r.db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 查询用户是否存在
	var admin model.SysAdmin
	if err := tx.First(&admin, id).Error; err != nil {
		tx.Rollback()
		return err
	}

	// 删除用户
	if err := tx.Delete(&model.SysAdmin{}, id).Error; err != nil {
		tx.Rollback()
		return err
	}

	// 删除关联的角色
	if err := tx.Where("admin_id = ?", id).Delete(&model.SysAdminRole{}).Error; err != nil {
		tx.Rollback()
		return err
	}

	// 提交事务
	if err := tx.Commit().Error; err != nil {
		tx.Rollback()
		return err
	}

	return nil
}

// UpdateSysAdminStatus 修改用户状态
func (r *AdminRepository) UpdateSysAdminStatus(id int, status int) error {
	// 使用事务确保操作的原子性
	tx := r.db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 查询用户是否存在
	var sysAdmin model.SysAdmin
	if err := tx.First(&sysAdmin, id).Error; err != nil {
		tx.Rollback()
		return err
	}

	// 更新状态
	sysAdmin.Status = status

	// 保存更改
	if err := tx.Save(&sysAdmin).Error; err != nil {
		tx.Rollback()
		return err
	}

	// 提交事务
	if err := tx.Commit().Error; err != nil {
		tx.Rollback()
		return err
	}

	return nil
}

// ResetSysAdminPassword 重置密码 util.EncryptionMd5(dto.Password)  todo 服务层完成
func (r *AdminRepository) ResetSysAdminPassword(id int, password string) error {
	// 使用事务确保操作的原子性
	tx := r.db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 查询用户是否存在
	var sysAdmin model.SysAdmin
	if err := tx.First(&sysAdmin, id).Error; err != nil {
		tx.Rollback()
		return err
	}

	// 更新密码
	sysAdmin.Password = password

	// 保存更改
	if err := tx.Save(&sysAdmin).Error; err != nil {
		tx.Rollback()
		return err
	}

	// 提交事务
	if err := tx.Commit().Error; err != nil {
		tx.Rollback()
		return err
	}

	return nil
}

// GetSysAdminList_back 分页查询用户列表
func (r *AdminRepository) GetSysAdminList_back(PageSize, PageNum int, Username, Status, BeginTime, EndTime string) (sysAdminVo []vo.SysAdminVo, count int64) {
	curDb := r.db.Table("sys_admin").
		Select("sys_admin.*, sys_post.post_name, sys_role.role_name, sys_dept.dept_name").
		Joins("LEFT JOIN sys_post ON sys_admin.post_id = sys_post.id").
		Joins("LEFT JOIN sys_admin_role ON sys_admin.id = sys_admin_role.admin_id").
		Joins("LEFT JOIN sys_role ON sys_role.id = sys_admin_role.role_id").
		Joins("LEFT JOIN sys_dept ON sys_dept.id = sys_admin.dept_id")
	if Username != "" {
		curDb = curDb.Where("sys_admin.username = ?", Username)
	}
	if Status != "" {
		curDb = curDb.Where("sys_admin.status = ?", Status)
	}
	if BeginTime != "" && EndTime != "" {
		curDb = curDb.Where("sys_admin.create_time BETWEEN ? AND ?", BeginTime, EndTime)
	}
	curDb.Count(&count)
	curDb.Limit(PageSize).Offset((PageNum - 1) * PageSize).Order("sys_admin.create_time DESC").Find(&sysAdminVo)
	return sysAdminVo, count
}

// GetSysAdminList 分页查询用户列表 - 返回领域模型，不返回VO
// 使用联表查询获取更完整的信息，但仍然返回领域模型 + 关联数据
// GetSysAdminList 分页查询用户列表
func (r *AdminRepository) GetSysAdminList(query query.SysAdminQuery) (dto.AdminListResult, error) {
	var result dto.AdminListResult
	result.RoleMapping = make(map[int]int)
	result.DeptNames = make(map[int]string)
	result.PostNames = make(map[int]string)
	result.RoleNames = make(map[int]string)

	// 查询管理员列表
	db := r.db.Model(&model.SysAdmin{})
	if query.Username != "" {
		db = db.Where("username = ?", query.Username)
	}
	if query.Status != "" {
		db = db.Where("status = ?", query.Status)
	}
	if query.BeginTime != "" && query.EndTime != "" {
		db = db.Where("create_time BETWEEN ? AND ?", query.BeginTime, query.EndTime)
	}

	// 计算总记录数
	if err := db.Count(&result.Total).Error; err != nil {
		return result, err
	}

	// 查询分页数据
	offset := (query.PageNum - 1) * query.PageSize
	if err := db.Offset(offset).Limit(query.PageSize).
		Order("create_time DESC").
		Find(&result.Admins).Error; err != nil {
		return result, err
	}

	// 收集需要查询的IDs
	adminIds := make([]int, 0, len(result.Admins))
	deptIds := make([]int, 0, len(result.Admins))
	postIds := make([]int, 0, len(result.Admins))

	for _, admin := range result.Admins {
		adminIds = append(adminIds, admin.ID)
		if admin.DeptId > 0 {
			deptIds = append(deptIds, admin.DeptId)
		}
		if admin.PostId > 0 {
			postIds = append(postIds, admin.PostId)
		}
	}

	// 批量查询部门
	if len(deptIds) > 0 {
		var depts []model.SysDept
		r.db.Where("id IN ?", deptIds).Find(&depts)
		for _, dept := range depts {
			result.DeptNames[int(dept.ID)] = dept.DeptName
		}
	}

	// 批量查询岗位
	if len(postIds) > 0 {
		var posts []model.SysPost
		r.db.Where("id IN ?", postIds).Find(&posts)
		for _, post := range posts {
			result.PostNames[int(post.ID)] = post.PostName
		}
	}

	// 批量查询角色关系和角色
	if len(adminIds) > 0 {
		var adminRoles []model.SysAdminRole
		r.db.Where("admin_id IN ?", adminIds).Find(&adminRoles)

		roleIds := make([]int, 0, len(adminRoles))
		for _, ar := range adminRoles {
			result.RoleMapping[ar.AdminId] = ar.RoleId
			roleIds = append(roleIds, ar.RoleId)
		}

		if len(roleIds) > 0 {
			var roles []model.SysRole
			r.db.Where("id IN ?", roleIds).Find(&roles)
			for _, role := range roles {
				result.RoleNames[int(role.ID)] = role.RoleName
			}
		}
	}

	return result, nil
}

// UpdatePersonal 修改个人信息
func (r *AdminRepository) UpdatePersonal(admin model.SysAdmin) (model.SysAdmin, error) {
	var existingAdmin model.SysAdmin

	// 使用事务来确保操作的原子性
	tx := r.db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 查询用户是否存在
	if err := tx.First(&existingAdmin, admin.ID).Error; err != nil {
		tx.Rollback()
		return model.SysAdmin{}, err
	}

	// 更新需要修改的字段
	if admin.Icon != "" {
		existingAdmin.Icon = admin.Icon
	}
	if admin.Username != "" {
		existingAdmin.Username = admin.Username
	}
	if admin.Nickname != "" {
		existingAdmin.Nickname = admin.Nickname
	}
	if admin.Phone != "" {
		existingAdmin.Phone = admin.Phone
	}
	if admin.Email != "" {
		existingAdmin.Email = admin.Email
	}
	if admin.Note != "" {
		existingAdmin.Note = admin.Note
	}

	// 保存更改
	if err := tx.Save(&existingAdmin).Error; err != nil {
		tx.Rollback()
		return model.SysAdmin{}, err
	}

	// 提交事务
	if err := tx.Commit().Error; err != nil {
		tx.Rollback()
		return model.SysAdmin{}, err
	}

	return existingAdmin, nil
}

// UpdatePersonalPassword 修改个人密码 todo  密码加密  在service层实现
func (r *AdminRepository) UpdatePersonalPassword(id int, newPassword string) (model.SysAdmin, error) {
	var sysAdmin model.SysAdmin

	// 使用事务来确保操作的原子性
	tx := r.db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 查询用户是否存在
	if err := tx.First(&sysAdmin, id).Error; err != nil {
		tx.Rollback()
		return model.SysAdmin{}, err
	}

	// 更新密码
	sysAdmin.Password = newPassword

	// 保存更改
	if err := tx.Save(&sysAdmin).Error; err != nil {
		tx.Rollback()
		return model.SysAdmin{}, err
	}

	// 提交事务
	if err := tx.Commit().Error; err != nil {
		tx.Rollback()
		return model.SysAdmin{}, err
	}

	return sysAdmin, nil
}
